/**
  ******************************************************************************
  * File Name          : ctrl_task.c
  * Description        : Code for data process applications
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "collector.h"
#include "tskcfg.h"
#include "ctrl_common.h"
#include "dwlcd.h"
#include "route.h"

TaskHandle_t xControl_Thd = NULL;
StaticTask_t xControl_Tcb;
StackType_t  xControl_Stk[ CONTROL_STACK_SIZE ];

volatile Ctr_TcTickersType Ctr_TcTickers = {0};

volatile uint8_t bj_act = 0;
volatile uint8_t zd_act = 0;
volatile uint8_t fn_act[CTR_FAN_CHANNEL_ALLNUM] = {0};
volatile uint8_t sl_act[CTR_SHL_CHANNEL_ALLNUM] = {0};
volatile uint8_t nq_act[CTR_NUQ_CHANNEL_ALLNUM] = {0};
volatile uint8_t vf_act[CTR_VFD_CHANNEL_ALLNUM] = {0};
volatile uint8_t vf_act_last[CTR_VFD_CHANNEL_ALLNUM] = {0};
volatile uint8_t dk_act[DKCTR_PT_CHANNEL_ALLNUM] = {0};
volatile uint8_t xc_act = 0;                                /* 小窗为子设备统一执行, 若后期需要分立执行 可改为数组 */


void Ctrl_RefreshStateFN(uint8_t force)
{
  if((force != 0) || (memcmp((void *)&Ctrl_StateFN, (void *)&Ctrl_StateFN_last, sizeof(Ctrl_StateFNType)) != 0))
	{
    Route_ec_tonet_fnst();
    
    Ctrl_StateFN_last = Ctrl_StateFN;
	}
}

void Ctrl_RefreshStateSL(uint8_t force)
{
  if((force != 0) || (memcmp((void *)&Ctrl_StateSL, (void *)&Ctrl_StateSL_last, sizeof(Ctrl_StateSLType)) != 0))
	{
    Route_ec_tonet_slst();
    
    Ctrl_StateSL_last = Ctrl_StateSL;
	}
}

void Ctrl_RefreshStateNQ(uint8_t force)
{
  if((force != 0) || (memcmp((void *)&Ctrl_StateNQ, (void *)&Ctrl_StateNQ_last, sizeof(Ctrl_StateNQType)) != 0))
	{
    Route_ec_tonet_nqst();
    
    Ctrl_StateNQ_last = Ctrl_StateNQ;
	}
}

void Ctrl_RefreshStateVF(uint8_t force)
{
  if((force != 0) || (memcmp((void *)&Ctrl_StateVF, (void *)&Ctrl_StateVF_last, sizeof(Ctrl_StateVFType)) != 0))
	{
    DW_Send_bpq();
    
    Route_ec_tonet_vfst();
    
    Ctrl_StateVF_last = Ctrl_StateVF;
	}
}

void Ctrl_RefreshStateDK(uint8_t force)
{
  if((force != 0) || (memcmp((void *)&Ctrl_StateDK, (void *)&Ctrl_StateDK_last, sizeof(Ctrl_StateDKType)) != 0))
	{
    Route_dj_tonet_ptstate();
    
    Ctrl_StateDK_last = Ctrl_StateDK;
	}
}

void vControl_Task( void * pvParameters )
{
  uint8_t ch,i;
	int16_t temper, nh3;
	uint8_t vf_force = 0;
  uint8_t xc_tick = 0;
	TickType_t tick;
  
	Ctr_TCTimerInit();
	
  tick = xTaskGetTickCount();
  
	while(1)
	{   
		if(Ctrl_ParaMD.mode != CTRL_MODE_MU)
		{
			temper = Collector_LocalData.average.temperature;
			nh3    = Collector_LocalData.average.nh3;
			
			Ctr_TcTickers.fan_tc_recont = 0;
			Ctr_TcTickers.shl_tc_recont = 0;
			Ctr_TcTickers.nuq_tc_recont = 0;
			for(i=0; i<CTR_VFD_CHANNEL_ALLNUM; i++)
			{
				Ctr_TcTickers.vfd_tc_recont[i] = 0;
			}

/*** 通道执行逻辑决策 ***/			
			switch(Ctrl_ParaMD.mode)
			{
				case CTRL_MODE_JT:
					Ctrl_fan_mode_jt(temper);
					Ctrl_shl_mode_jt(temper);
					Ctrl_nuq_mode_jt(temper);
					break;
				
				case CTRL_MODE_DL:
					Ctrl_fan_mode_dl(temper, Ctr_TcTickers.fan_tc_ticker, Ctr_TcTickers.vfd_tc_ticker);
					Ctrl_shl_mode_dl(temper, Ctr_TcTickers.shl_tc_ticker);
					Ctrl_nuq_mode_dl(temper, Ctr_TcTickers.nuq_tc_ticker);
					break;
				
				case CTRL_MODE_SK:
					Ctrl_fan_mode_sk(temper, Ctr_TcTickers.fan_tc_ticker, Ctr_TcTickers.vfd_tc_ticker);
					Ctrl_shl_mode_sk(temper, Ctr_TcTickers.shl_tc_ticker);
					Ctrl_nuq_mode_sk(temper, Ctr_TcTickers.nuq_tc_ticker);
					break;
				
				case CTRL_MODE_ZN:
					Ctrl_fan_mode_zn(temper, Ctr_TcTickers.fan_tc_ticker, Ctr_TcTickers.vfd_tc_ticker);
					Ctrl_shl_mode_zn(temper, Ctr_TcTickers.shl_tc_ticker);
					Ctrl_nuq_mode_zn(temper, Ctr_TcTickers.nuq_tc_ticker);
					break;
				
				default:
					vTaskDelay(40);
					continue;
			}
      
      Ctrl_fan_nh3(nh3);
      
/*** 时控的控制和维护 ***/	      
			if(Ctr_TcTickers.fan_tc_recont != 0)
			{
				Ctr_TcTickers.fan_tc_ticker_en = 1;
			}
			else
			{
				Ctr_TcTickers.fan_tc_ticker_en = 0;
				Ctr_TcTickers.fan_tc_ticker = 0;
			}
			
			if(Ctr_TcTickers.shl_tc_recont != 0)
			{
				Ctr_TcTickers.shl_tc_ticker_en = 1;
			}
			else
			{
				Ctr_TcTickers.shl_tc_ticker_en = 0;
				Ctr_TcTickers.shl_tc_ticker = 0;
			}
			
			if(Ctr_TcTickers.nuq_tc_recont != 0)
			{
				Ctr_TcTickers.nuq_tc_ticker_en = 1;
			}
			else
			{
				Ctr_TcTickers.nuq_tc_ticker_en = 0;
				Ctr_TcTickers.nuq_tc_ticker = 0;
			}
			
			for(i=0; i<CTR_VFD_CHANNEL_ALLNUM; i++)
			{
				if(Ctr_TcTickers.vfd_tc_recont[i] != 0)
				{
					Ctr_TcTickers.vfd_tc_ticker_en[i] = 1;
				}
				else
				{
					Ctr_TcTickers.vfd_tc_ticker_en[i] = 0;
					Ctr_TcTickers.vfd_tc_ticker[i] = 0;
				}
			}

/*** 通道逻辑的执行 ***/	      
			for(ch=0; ch<CTR_FAN_CHANNEL_ALLNUM; ch++)
			{
        CtrFan_SetActuator(fn_act[ch], ch, 0);
			}
			Ctrl_RefreshStateFN(0);
			
			for(ch=0; ch<CTR_SHL_CHANNEL_ALLNUM; ch++)
			{
        CtrShl_SetActuator(sl_act[ch], ch, 0);
			}
			Ctrl_RefreshStateSL(0);
			
			for(ch=0; ch<CTR_NUQ_CHANNEL_ALLNUM; ch++)
			{
        CtrNuq_SetActuator(nq_act[ch], ch, 0);
			}
			Ctrl_RefreshStateNQ(0);
			
      /* 如果执行改变,则立即执行一次,如果执行未变,则5秒强制执行一次 */
			if((memcmp((void*)vf_act, (void*)vf_act_last, CTR_VFD_CHANNEL_ALLNUM) != 0) || (vf_force++ > 5))
			{
        vf_force = 0;
        
				for(ch=0; ch<CTR_VFD_CHANNEL_ALLNUM; ch++)
				{
					CtrVfd_Actuator(vf_act[ch], ch, 0);
				}
				memcpy((void*)vf_act_last, (void*)vf_act, CTR_VFD_CHANNEL_ALLNUM);
			}
			Ctrl_RefreshStateVF(0);
		}

    /* 模式外 */
    Ctrl_dk(&Sys_Runtime);
    for(i=0; i<DKCTR_PT_CHANNEL_ALLNUM; i++)
    {
      CtrDk_SetActuator(dk_act[i], i);
    }
    Ctrl_RefreshStateDK(0);
    
    
    Ctrl_bj(Collector_LocalData.average.temperature);
    CtrBj_SetActuator(bj_act);
    
    Ctrl_zd();
    CtrZd_SetActuator(zd_act);
    
    if(xc_tick++ >= 60)
    {
      xc_tick = 0;
      Ctrl_xc(Collector_LocalData.average.temperature);
      CtrXc_SetActuator(xc_act);
    }
    
    vTaskDelayUntil(&tick, 1000);
	}
}
